package cn.demoncat.util.lang;

import cn.demoncat.util.exception.BizRuntimeException;
import cn.demoncat.util.exception.ParamRuntimeException;
import cn.demoncat.util.lang.constant.IntegerConstant;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 描述：Integer工具
 *
 * 注：Integer最长9位（10位的21...）
 * 
 * @author 延晓磊
 *
 * @since 2017年7月10日
 */
public final class IntegerUtil {

	/**
	 * 判断为空或0
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年1月16日
	 */
	public static boolean isEmpty(Integer o) {
		return o == null || o == 0;
	}

	/**
	 * 判断非空或0
	 *
	 * @param o
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年1月16日
	 */
	public static boolean isNotEmpty(Integer o) {
		return !isEmpty(o);
	}

	/**
	 * 判断为空或0时抛异常
	 *
	 * @param o
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2022年03月25日
	 */
	public static Integer checkEmpty(Integer o){
		if (isEmpty(o)) {
			throw ParamRuntimeException.NULL;
		}
		return o;
	}

	/**
	 * null转0
	 * 
	 * @param o
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static Integer toEmpty(Integer o) {
		return o == null ? 0 : o;
	}

	/**
	 * 如果o为null，执行 consumer.accept(“”)
	 *
	 * 例：IntegerUtil.toEmpty(data.getPid(), data::setPid);
	 *
	 * @param o
	 * @param consumer
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static void toEmpty(Integer o, Consumer<Integer> consumer) {
		if (o == null) {
			consumer.accept(0);
		}
	}

	/**
	 * null/0 转默认值
	 * 
	 * @param o		数据
	 * @param def	默认值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static Integer toDefault(Integer o, Integer def) {
		return isEmpty(o) ? def : o;
	}

	/**
	 * null/0 转默认值
	 *
	 * @param o		数据
	 * @param def	默认值
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2018年6月5日
	 */
	public static Integer toDefault(Integer o, Supplier<Integer> def) {
		return isEmpty(o) ? def.get() : o;
	}

	/**
	 * 转换为字符串
	 *
	 * @param o
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年11月23日
	 */
	public static String toString(Integer o){
		return o == null ? null : o.toString();
	}

	/**
	 * 转换为字符串
	 *
	 * @param o
	 * @param def
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2021年11月23日
	 */
	public static String toString(Integer o, Integer def){
		return o == null ? toString(def) : o.toString();
	}

	/**
	 * 转换字符串为Integer
	 *
	 * @param num
	 * @param def	默认值
	 * @return 如果字符串为空则返回def，如果字符串非数值则异常
	 *
	 * @author 延晓磊
	 *
	 * @since 2017年1月5日
	 */
	public static Integer valueOf(String num, Integer def) {
		num = StringUtils.trimToNull(num);
		// 如果为空，返回def
		if (StringUtil.isBlank(num)) {
			return def;
		}
		// 非空转换，格式错误抛异常
		return Integer.valueOf(num);
	}

	/**
	 * 转换字符串为Integer
	 *
	 * @param num
	 * @return 如果字符串为空则返回null，如果字符串非数值则异常
	 *
	 * @author 延晓磊
	 *
	 * @since 2017年1月5日
	 */
	public static Integer valueOf(String num) {
		return valueOf(num, null);
	}

	/**
	 * 转换字符串为Integer
	 * 
	 * @param num
	 * @return 如果字符串为空则返回0，如果字符串非数值则异常
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年1月5日
	 */
	public static Integer valueOfZero(String num) {
		return valueOf(num, 0);
	}

	/**
	 * 功能描述：转换为Long
	 *
	 * @param i
	 * @return long
	 * 
	 * @author 延晓磊
	 *
	 * @since 2017年1月5日
	 */
	public static Long toLong(Integer i) {
		if (i == null)
			return null;
		return i.longValue();
	}
	
	/**
	 * 转换Object为Integer
	 * 
	 * @param num
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020-9-15
	 */
	public static Integer cast(Object num) {
		if (num == null) {
			return null;
		}
		if (num instanceof Integer) {
			return (Integer)num;
		}
		if (num instanceof Long) {
			return ((Long)num).intValue();
		}
		if (num instanceof Number) {
			return ((Number)num).intValue();
		}
		String str = num.toString();
		if (str.matches(RegexpUtil.NumberRex.INTEGER)) {
			return valueOf(num.toString());
		}
		return null;
	}

	/**
	 * 判断区间 min <= v <= max
	 *
	 * @param v
	 * @param min
	 * @param max
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年2月5日
	 */
	public static boolean isRange(int v, int min, int max) {
		return v >= min && v <= max;
	}

	/**
	 * 限定区间 min <= v <= max
	 *
	 * @param v
	 * @param min
	 * @param max
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年2月5日
	 */
	public static int range(int v, int min, int max) {
		if(v < min){
			return min;
		}else return Math.min(v, max);
	}

	/**
	 * 判断区间 0 <= v <= max
	 *
	 * @param v
	 * @param max
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年2月5日
	 */
	public static boolean isRange(int v, int max) {
		return isRange(v, 0, max);
	}

	/**
	 * 获取区间 0 <= v <= max
	 *
	 * @param v
	 * @param max
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年2月5日
	 */
	public static int range(int v, int max) {
		return range(v, 0, max);
	}

	/**
	 * 运算：加 +
	 *
	 * @param vs	运算数
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int add(int ...vs) {
		if (vs == null) {
			return 0;
		}
		if (vs.length == 1) {
			return vs[0];
		}
		if (vs.length == 2) {
			return vs[0] + vs[1];
		}
		return Arrays.stream(vs).reduce(Integer::sum).getAsInt();
	}

	/**
	 * 运算：减 -
	 *
	 * @param vs	运算数
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int subtract(int ...vs) {
		if (vs == null) {
			return IntegerConstant.N0;
		}
		if (vs.length == 1) {
			return vs[0];
		}
		if (vs.length == 2) {
			return vs[0] - vs[1];
		}
		return Arrays.stream(vs).reduce((a,b) -> a - b).getAsInt();
	}

	/**
	 * 运算：减 -
	 *
	 * @param vs	运算数
	 *
	 * @return 结果为负时返回0
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int subtractZero(int ...vs) {
		int num = subtract(vs);
		if (num < 0) {
			return IntegerConstant.N0;
		}
		return num;
	}

	/**
	 * 运算：减 -
	 *
	 * @param min	最小值，默认0
	 * @param msg	异常消息（结果小于min）
	 * @param vs	运算数
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int subtract(Integer min, String msg, int ...vs) {
		// 计算
		int r = subtract(vs);
		// 比较
		if (min == null) {
			min = IntegerConstant.N0;
		}
		if (r < min) {
			if (msg == null) {
				msg = "计算结果不能小于" + min;
			}
			throw new BizRuntimeException(msg);
		}
		return r;
	}

	/**
	 * 运算：减 -
	 *
	 * @param msg	异常消息（结果小于0）
	 * @param vs	运算数
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int subtractZero(String msg, int ...vs) {
		return subtract(IntegerConstant.N0, msg, vs);
	}

	/**
	 * 运算：乘 *
	 *
	 * @param vs	运算数
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int multiply(int ...vs) {
		if (vs == null) {
			return IntegerConstant.N0;
		}
		if (vs.length == 1) {
			return vs[0];
		}
		if (vs.length == 2) {
			return vs[0] * vs[1];
		}
		return Arrays.stream(vs).reduce((a,b) -> a * b).getAsInt();
	}

	/**
	 * 运算：除 /
	 *
	 * @param vs	运算数：2个及以上，除数 == 0 = 被除数（不再抛异常 java.lang.ArithmeticException: / by zero）
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2019年11月11日
	 */
	public static int divide(int ...vs) {
		return Arrays.stream(vs).reduce((a,b) -> isEmpty(b) ? a : a / b).getAsInt();
	}
}
